#pragma GCC optimize(2)
#include <iostream>
#include <queue>
#include <map>
#include <unordered_map>
#include <vector>
#include <algorithm>
#include <cmath>
#include <string>
#include <cstring>
#include <set>
#include <unordered_set>
#define IOS ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int N=5e5+10;
int e[N],ne[N],h[N],idx;
int f[N][3];
int g[N][3];
int st[N];
string s;
void add(int a,int b)
{
	e[idx]=b;
	ne[idx]=h[a];
	h[a]=idx++;
}
void dfs1(int u)
{
	st[u]=1;
	int d=0;
	for(int i=1;i<=s[u]-'0';i++)
	{
		if(st[u+i+d])
		{
			i--;
			d++;
			continue; 
		}
		add(u+1,u+i+1+d);
		dfs1(u+i+d);
	}
}
void dfs(int u)
{
	g[u][0]=f[u][0]=1;
	for(int i=h[u];~i;i=ne[i])
	{
		int j=e[i];
		dfs(j);
//		cout<<u<<' '<<j<<endl;
		if(ne[i]==-1 && i==h[u])
		{
			f[u][0]+=min(f[j][1],f[j][2]);
		    f[u][1]+=min(f[j][0],f[j][2]);
		    f[u][2]+=min(f[j][0],f[j][1]);
		    
		    g[u][0]+=max(g[j][1],g[j][2]);
		    g[u][1]+=max(g[j][0],g[j][2]);
		    g[u][2]+=max(g[j][0],g[j][1]);
		    break;
		}
		else if(ne[i]!=-1 && i==h[u])
		{
			int t=e[ne[i]];
			dfs(t);
			f[u][0]+=min(f[j][1]+f[t][2],f[j][2]+f[t][1]);
			f[u][1]+=min(f[j][0]+f[t][2],f[j][2]+f[t][0]);
			f[u][2]+=min(f[j][0]+f[t][1],f[j][1]+f[t][0]);
			
			g[u][0]+=max(g[j][1]+g[t][2],g[j][2]+g[t][1]);
			g[u][1]+=max(g[j][0]+g[t][2],g[j][2]+g[t][0]);
			g[u][2]+=max(g[j][0]+g[t][1],g[j][1]+g[t][0]);
			break;
		}
		
	}
}
int main()
{
	memset(h,-1,sizeof(h));
	cin>>s;

	dfs1(0);
	dfs(1);
	cout<<max({g[1][0],g[1][1],g[1][2]})<<' ';
	cout<<min({f[1][0],f[1][1],f[1][2]});

	return 0;
}

